package cliente;


import aso.upna.busControl.EndStream;
import aso.upna.exceptions.NoFileLoaded;
import aso.upna.interfaces.AudioPlayerInterface;
import java.io.File;
import java.net.Socket;
import org.gstreamer.*;
import org.gstreamer.elements.PlayBin;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author triki
 */
public class Hilo implements Runnable,AudioPlayerInterface {

    private AudioPlayer player;
    private Socket sock;
    private String filename;
    private PlayBin playbin;

    public Hilo(Socket sock,String filename)
    {
        this.sock = sock;
        this.filename = new String(filename);
    }

    //Este metodo debe invocarse antes de empezar la reproduccion pues es
    //el encargado de configurar todo el sistema de reproduccion.

    public void startUpAudioPlayer()
    {
         String[] args = new String[1];
         args[0] = "";
         args = Gst.init("AudioPlayer", args);

        buildAudioPlayer();
        setFileName();

        //Ponemos el reproductor configurado en A LA ESPERA.
        playbin.setState(State.READY);
    }

    //Este metodo construye el reproductor de musica y lo configura.
    private void buildAudioPlayer()
    {
        playbin = new PlayBin("Mp3AudioPlayer");

        //Añadimos los listeners al bus. Los listener nos avisaran de los mensajes
        //introducidos en el Bus.

        //Añadimos un listener para cuando finaliza el stream.
        playbin.getBus().connect(new EndStream(playbin));
        //Añadimos un listener para obtener el tag del fichero MP3. -> Implementar en una clase
        playbin.getBus().connect(new Bus.TAG() {
          TagList tagList;
            public void tagsFound(GstObject arg0, TagList arg1) {
                for (String tagName : arg1.getTagNames()) {
                    for (Object tagData : arg1.getValues(tagName)) {
                        System.out.printf("[%s]=%s\n", tagName, tagData.toString());
                    }
                }
            }
        });

        //Añadimos un listener para los errores -> Implementar en una clase
        playbin.getBus().connect(new Bus.ERROR() {
            public void errorMessage(GstObject source, int code, String message) {
                System.out.println("Error occurred: " + message);
                Gst.quit();
            }
        });

        /*playbin.getBus().connect(new Bus.STATE_CHANGED() {
            public void stateChanged(GstObject source, State old, State current, State pending) {
                if (source == playbin) {
                    System.out.println("Pipeline state changed from " + old + " to " + current);
                }
            }
        });*/

        //Indicamos al Bus que lo vacie automaticamente. No es necesario.
        playbin.getBus().setFlushing(true);
    }

    //Metodo principal. Carga en la pipe el fichero expecificado como
    //argumento en la construccion de la clase.

    public void setFileName()
    {
        playbin.setInputFile(new File(this.filename));
        System.out.println("Fichero Cargado");
    }

    //Metodo sobre cargado. Permite cargar otro fichero distinto al pasado
    //como argumento en el constructor. Muy util para cargar un segundo fichero.
    //para futuras reproducciones de audio.
    
    public void setFileName(String filename) throws NoFileLoaded
    {
        if(filename == null)
            throw new NoFileLoaded();
        else
        {
            this.filename = new String(filename);

            //Cargamos el fichero a reproducir.
            playbin.setInputFile(new File(this.filename));
            System.out.println("Fichero Cargado");
        }
    }

    public void RegisterObject(AudioPlayer gui)
    {
        player = gui;
    }

    //Empieza a ejecutarse el hilo. Recuerda que el hilo siempre empieza
    //ejecutandose por defecto.
    public void run()
    {        
        
        playbin.setState(State.PLAYING);
        System.out.println("> Playing...");
        Gst.main();

    }

    public String getCurrentPosition()
    {
        return playbin.queryPosition().toString();
    }

    public void getCurrentDuration()
    {
        if(playbin.isPlaying())
            System.out.println("tiempo: "+playbin.queryDuration().toString());
 
    }

    //Empieza o reanuda la cancion
    public void play() {
        playbin.setState(State.PLAYING);
        System.out.println("> Playing...");
    }

    public void pause() {
        playbin.setState(State.PAUSED);
        System.out.println("> Audio Paused.");
    }

    public void stop() {
        //Paramos la musica.
        playbin.setState(State.NULL);
        //Gst.quit();
        System.out.println("Musica Parada");
    }

}
